//
//  ILGRequest.m
//  ILGLibProjectDEV
//
//  Created by Happy on 8/27/16.
//  Copyright © 2016 Happy. All rights reserved.
//

#import "ILGRequest.h"

#import "ILGRequestConfig.h"
#import "ILGEncrypt.h"

@interface ILGRequest ()
#ifdef ILGAFNetworking
@property (nonatomic, strong) AFHTTPSessionManager *httpOperationManager;
#endif
@end

@implementation ILGRequest

+ (instancetype)requestManager {
    return [[self alloc] init];
}

- (instancetype)init {
    return [self initWithBaseURL:nil];
}

- (id)initWithBaseURL:(NSString *)baseURL {
    if (self = [super init]) {
#ifdef ILGAFNetworking
        NSURL *url = baseURL.length ? [NSURL URLWithString:baseURL]:nil;
        _httpOperationManager = [[AFHTTPSessionManager alloc] initWithBaseURL:url];
        _httpOperationManager.requestSerializer = [AFJSONRequestSerializer serializer];
        _httpOperationManager.responseSerializer = [AFJSONResponseSerializer serializer];
        _httpOperationManager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/plain", nil];
        _httpOperationManager.requestSerializer.timeoutInterval = 20;
#endif
    }
    return self;
}

- (void)setRequestSerializer:(ILGRequestSerializer)requestSerializer {
#ifdef ILGAFNetworking
    if (requestSerializer == ILGRequestSerializerHTTP) {
        self.httpOperationManager.requestSerializer = [AFHTTPRequestSerializer serializer];
    } else {
        self.httpOperationManager.requestSerializer = [AFJSONRequestSerializer serializer];
    }
#endif
}

- (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field {
#ifdef ILGAFNetworking
    [self.httpOperationManager.requestSerializer setValue:value forHTTPHeaderField:field];
#endif
}

+ (void)get:(NSString *)URLString parameter:(NSDictionary *)parameter success:(ILGRequestSuccess)success failure:(ILGRequestFailure)failure {
    [[self requestManager] get:URLString parameter:parameter success:success failure:failure];
}

+ (void)post:(NSString *)URLString parameter:(NSDictionary *)parameter success:(ILGRequestSuccess)success failure:(ILGRequestFailure)failure {
    [[self requestManager] post:URLString parameter:parameter success:success failure:failure];
}

- (void)get:(NSString *)URLString parameter:(NSDictionary *)parameter success:(ILGRequestSuccess)success failure:(ILGRequestFailure)failure {
#ifdef ILGAFNetworking
    NSURLSessionDataTask *dataTask = [_httpOperationManager GET:URLString parameters:parameter progress:^(NSProgress * _Nonnull downloadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        [ILGRequest printResponse:task.currentRequest.URL responseObject:responseObject error:nil];
        success ? success(responseObject):nil;
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [ILGRequest printResponse:task.currentRequest.URL responseObject:nil error:error];
        failure ? failure([self p_localizedError:error task:task]):nil;
        
    }];
    
    [ILGRequest printRequestInfo:dataTask.currentRequest.URL params:parameter];
#endif
}

- (void)post:(NSString *)URLString parameter:(NSDictionary *)parameter success:(ILGRequestSuccess)success failure:(ILGRequestFailure)failure {
#ifdef ILGAFNetworking
    NSURLSessionDataTask *dataTask = [_httpOperationManager POST:URLString parameters:parameter progress:^(NSProgress * _Nonnull uploadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        
        [ILGRequest printResponse:task.currentRequest.URL responseObject:responseObject error:nil];
        success ? success(responseObject):nil;
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
        [ILGRequest printResponse:task.currentRequest.URL responseObject:nil error:error];
        failure ? failure([self p_localizedError:error task:task]):nil;
        
    }];
    
    [ILGRequest printRequestInfo:dataTask.currentRequest.URL params:parameter];
#endif
}

- (void)POST:(NSString *)URLString
  parameters:(NSDictionary *)parameters
constructingBodyWithBlock:(void(^)(id<AFMultipartFormData>  _Nonnull formData))block
    progress:(void(^)(NSProgress * _Nonnull uploadProgress))progress
     success:(ILGRequestSuccess)success
     failure:(ILGRequestFailure)failure {
#ifdef ILGAFNetworking
    NSURLSessionDataTask *dataTask = [self.httpOperationManager POST:URLString parameters:parameters constructingBodyWithBlock:block progress:progress success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        
        [ILGRequest printResponse:task.currentRequest.URL responseObject:responseObject error:nil];
        success ? success(responseObject):nil;
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
        [ILGRequest printResponse:task.currentRequest.URL responseObject:nil error:error];
        failure ? failure([self p_localizedError:error task:task]):nil;
        
    }];
    
    [ILGRequest printRequestInfo:dataTask.currentRequest.URL params:parameters];
#endif
}

- (void)DELETE:(NSString *)URLString parameters:(NSDictionary *)parameters success:(ILGRequestSuccess)success failure:(ILGRequestFailure)failure {
#ifdef ILGAFNetworking
    NSURLSessionDataTask *dataTask = [_httpOperationManager DELETE:URLString parameters:parameters success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        [ILGRequest printResponse:task.currentRequest.URL responseObject:responseObject error:nil];
        success ? success(responseObject):nil;
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [ILGRequest printResponse:task.currentRequest.URL responseObject:nil error:error];
        failure ? failure([self p_localizedError:error task:task]):nil;
        
    }];
    
    [ILGRequest printRequestInfo:dataTask.currentRequest.URL params:parameters];
#endif
}

- (void)uploadPicture:(NSString *)URLString params:(NSDictionary *)params imageArr:(NSArray<UIImage *> *)imageArr nameArr:(NSArray *)nameArr fileNameArr:(NSArray *)fileNameArr success:(ILGRequestSuccess)success failure:(ILGRequestFailure)failure {
    [self setValue:@"multipart/form-data" forHTTPHeaderField:@"Content-Type"];
    
    NSMutableArray *fileArr = [NSMutableArray arrayWithCapacity:0];
    for (int i = 0; i < imageArr.count; i++) {
        UIImage *image = imageArr[i];
        NSData *imageData = [image ilg_imageCompress:500 compression:0.5];
        [fileArr addObject:imageData];
    }
    [self uploadFile:URLString parameters:params files:fileArr names:nameArr fileNames:fileNameArr mimeType:@"image/jpeg" progress:nil success:success failure:failure];
}



#pragma mark - Private Methods

- (void)uploadFile:(NSString *)URLString
        parameters:(NSDictionary *)parameters
             files:(NSArray<NSData *> *)files
             names:(NSArray *)names
         fileNames:(NSArray *)fileNames
          mimeType:(NSString *)mimeType
          progress:(void(^)(NSProgress * _Nonnull uploadProgress))progress
           success:(ILGRequestSuccess)success
           failure:(ILGRequestFailure)failure {
#ifdef ILGAFNetworking
    [self.httpOperationManager POST:URLString parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
        for (int index = 0; index < files.count; index++) {
            [formData appendPartWithFileData:files[index] name:names[index] fileName:fileNames[index] mimeType:mimeType];
        }
    } progress:^(NSProgress * _Nonnull uploadProgress) {
        progress ? progress(uploadProgress):nil;
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        success ? success(responseObject):nil;
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        failure ? failure([self p_localizedError:error task:task]):nil;
    }];
#endif
}

+ (void)printRequestInfo:(NSURL *)url params:(NSDictionary *)parameter {
    ILGRequestLog(@"RequestUrl->%@", url.absoluteString);
    ILGRequestLog(@"RequestParameter->%@", [ILGEncrypt getKeyValuedString:parameter]);
}

+ (void)printResponse:(NSURL *)url responseObject:(id)responseObject error:(NSError *)error {
    if (error) {
        ILGRequestLog(@"ResponseUrl->%@", [NSString stringWithFormat:@"%@",url.absoluteString]);
        ILGRequestLog(@"ResponseError->%@", error);
    } else {
        ILGRequestLog(@"ResponseUrl->%@", [NSString stringWithFormat:@"%@", url.absoluteString]);
        
        if (responseObject) {
            NSData *data = [NSJSONSerialization dataWithJSONObject:responseObject options:NSJSONWritingPrettyPrinted error:nil];
            ILGRequestLog(@"ResponseJsonString->%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
        }
    }
}

- (NSError *)p_localizedError:(NSError *)error task:(NSURLSessionDataTask *)task {
    NSMutableDictionary *mutUserInfo = error.userInfo.mutableCopy;
    NSString *errorMsg = nil;
    
    switch (error.code) {
        case -1001://NSURLErrorTimedOut
            errorMsg = @"请求超时";
            break;
        case -1002://NSURLErrorUnsupportedURL
            errorMsg = @"不支持的URL地址";
            break;
        case -1003://NSURLErrorCannotFindHost
            errorMsg = @"找不到服务器";
            break;
        case -1004://NSURLErrorCannotConnectToHost
            errorMsg = @"连接不上服务器";
            break;
        case -1005://NSURLErrorNetworkConnectionLost
            errorMsg = @"网络连接异常";
            break;
        case -1009://NSURLErrorNotConnectedToInternet
            errorMsg = @"无网络连接";
            break;
        default:
        {
            NSInteger statusCode = ((NSHTTPURLResponse *)task.response).statusCode;
            if (statusCode == 200) { //服务器响应正常，可能是客户端数据解析等错误
                errorMsg = @"本地错误";
            } else if (statusCode == 0) {
                errorMsg = @"本地错误";
            } else {
                errorMsg = @"服务器或者本地网络配置错误";
            }
        }
            break;
    }
    
#ifdef DEBUG
    errorMsg = [errorMsg stringByAppendingString:[NSString stringWithFormat:@",\ncode=%d", (int)error.code]];
#endif
    mutUserInfo[@"NSLocalizedDescription"] = errorMsg;
    NSError *localError = [NSError errorWithDomain:error.domain code:error.code userInfo:mutUserInfo];
    return localError;
}
@end

@implementation ILGRequest (NetworkReachability)
+ (void)startMonitoring {
#ifdef ILGAFNetworking
    [[AFNetworkReachabilityManager sharedManager] startMonitoring];
#endif
}

+ (void)setReachabilityStatusChangeBlock:(void (^)(NSInteger status))block {
#ifdef ILGAFNetworking
    [[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:block];
#endif
}
@end
